package own.stu.jobgib.playown.vediodown.common.service;

import cn.hutool.core.io.IoUtil;
import com.google.gson.Gson;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.asynchttpclient.AsyncHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import own.stu.jobgib.playown.vediodown.common.config.DefaultConfig;
import own.stu.jobgib.playown.vediodown.common.model.SimpleMediaItem;
import sun.nio.ch.IOUtil;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class BaseDownloadService {

    private static Logger logger = LoggerFactory.getLogger(BaseDownloadService.class);
    protected AsyncHttpClient client;
    protected Gson gson;

    protected BaseDownloadService(DefaultConfig cfg, String path) {
        this.path = path;
        this.SHORT_LINK_URL = cfg.getShortLinkUrl();
        client = cfg.getClient();
        gson = cfg.getGson();
        createDirIfNotEx();
    }

    private void createDirIfNotEx() {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    private BaseDownloadService() {
    }

    static protected String path = "/Users/qim/Desktop/bili/";
    public static String cookies_path = "/Users/qim/Library/Application Support/Google/Chrome/Default";
    protected String SHORT_LINK_URL;

    public boolean download(SimpleMediaItem item, Long userId) {
        List<String> blackLists = blackListByUserId(userId);
        if (CollectionUtils.isNotEmpty(blackLists)) {
            for (String b : blackLists) {
                if (b.indexOf(item.getBvId()) >= 0 || b.indexOf(item.getTitle()) >= 0) {
                    logger.info("bvId is already download");
                    return false;
                }
            }
        }
        return download(item);
    }

    public boolean download(SimpleMediaItem item) {
        //threadPool.execute(() -> process(item));
        process(item);
        return true;
    }

    private void process(SimpleMediaItem item) {
        assert StringUtils.isNotBlank(item.getCover())
                && StringUtils.isNotBlank(item.getCoverTitle())
                && StringUtils.isNotBlank(item.getBvId())
                ;
        // 这里 coverTitle 如果有空格，可以正常输出为文件名；如果 -O xx xx.jpg 则出现转义问题
        process("wget", "-O", path + "/" + item.getCoverTitle(), item.getCover());
        process("yt-dlp",
                "-P " + path,
                "-o",
                item.getVedioTitle(),
                "--cookies-from-browser", "chrome:" + cookies_path,
                SHORT_LINK_URL + item.getBvId());
    }

    public static void process(String... cmds) {
        try {

            // ProcessBuilder processBuilder = new ProcessBuilder("sh", "/Users/qim/Documents/idea-code/play-own/src/main/java/own/stu/jobgib/playown/vediodown/script.sh");
            ProcessBuilder processBuilder = new ProcessBuilder();
            processBuilder.command(cmds);
            Process process = processBuilder.start();

            // 获取Shell脚本输出
            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            process.waitFor(1, TimeUnit.MINUTES);
//            process.waitFor();
            int exitValue = process.exitValue();
            if (exitValue != 0) {
                logger.error("errorCode: {}, \n errMsg: {}", exitValue, getMessage(process.getErrorStream()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // not suit for big memory
    public static String getMessage(InputStream input) throws IOException {
        return new String(IoUtil.readUtf8(input));
    }

    protected static Map<Long, List<String>> blackLislMap = new HashMap<>();


    private static List<String> blackListByUserId(Long userId) {
        return blackLislMap.get(userId);
    }

    public String getCookies_path() {
        return cookies_path;
    }
}
